Detecting Multiple DXL Scripts

Greetings,

I have a dxl script that operates using a dialog box.  Is there a way I can prevent multiple instances of this from occurring?  Here is the scenerio.  Select an object in the DOORS module.  Select the script from a menu selection.  Go back to the DOORS module and select another object.  Select the script from the menu selection.  Now I have two dialog boxes, one from the first object and one from the second object.

Same thing can be done with the dxl window.  Load a dxl script and hit Run.   Go back to the dxl window and hit Run again, now there are two dialog boxes.

Thanks a bunch!

Greg


GregM_dxler - Tue Jul 02 12:23:11 EDT 2013

Re: Detecting Multiple DXL Scripts
adevicq - Tue Jul 02 12:40:00 EDT 2013

Hi,

The only method I know is called a "semaphore" (hope it's the same term in English...). It's a kind of token that says: "hey, I'm already busy".

When you start your code, the first thing to do is to try to take the token. You only free it at the very end.

Then, when you try to take the token, you check if it's available. If not, it has been taken by another instance. You must stop.

If it is available, you take it and mark it as not available.

You can use a file to materialize the token. For example you can create a file called "semaphore" (or whatever you want) in a dedicated folder and you delete it at the end.

The when you start your code if the file already exists you must stop at once. Else you create your semaphore, do what you have to do and at the end of your process you delete it.

The only issue is: if your code crashes. In this case the file already exists even if your code is not running. You must have an emergency procedure that resets your semaphore.

Hope this helps.

Alain

 

Re: Detecting Multiple DXL Scripts
Mike.Scharnow - Tue Jul 02 13:13:22 EDT 2013

One alternative to creating a semaphore using a file would be to create one using a top level DXL context variable, like "MonitorWidth" (check https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014702697 for an explanation)

 

An advantage would be that if the code crashes, you only would have to restart DOORS instead of an emergency procedure.

 

Best regards,
Mike

Re: Detecting Multiple DXL Scripts
GregM_dxler - Tue Jul 02 14:17:35 EDT 2013

Mike.Scharnow - Tue Jul 02 13:13:22 EDT 2013

One alternative to creating a semaphore using a file would be to create one using a top level DXL context variable, like "MonitorWidth" (check https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014702697 for an explanation)

 

An advantage would be that if the code crashes, you only would have to restart DOORS instead of an emergency procedure.

 

Best regards,
Mike

Thank you both for replying.  I didn't think about a semiphore, even though I use something similar to remember something.  Unfortunately, the script must be able to work with offsite people who work through citrix and having files on local computers is tricky since they use a different set up.

I'm not sure how to use a global variable, such as MonitorWidth.  It is not in the dxl reference manual.

However, this did give me an idea.  I searched through the manual and found the commands setServerMonitor() and serverMonitorIsOn.  According to the manual, setServerMonitor(on) is suppose to activate a Rational DOORS Server Monitor which monitors client server communications.  Although I don't see anything when I set it on (client side).

I was able to make a small program that would set the monitor on when the dialog box was active and set it off when it was completed and this would prevent a second occurance (pretty slick I might add).  But I don't know if I can reliably use this.  It seemed like it was off initially, but will remember the setting when I close doors and restart.

Is there some other type global variable I might be able to use?

Thanks again for your replies!

Greg

Re: Detecting Multiple DXL Scripts
GregM_dxler - Tue Jul 02 15:39:46 EDT 2013

Mike.Scharnow - Tue Jul 02 13:13:22 EDT 2013

One alternative to creating a semaphore using a file would be to create one using a top level DXL context variable, like "MonitorWidth" (check https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014702697 for an explanation)

 

An advantage would be that if the code crashes, you only would have to restart DOORS instead of an emergency procedure.

 

Best regards,
Mike

Did a search to find the entire thread on the massive memory leak.  It can be found at https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014629839

Turns out it is monitorWidth, not MonitorWidth....

I was able to read the current value (20) and also to change it.

Still have the same sort of problem, where I don't know what it will initially be set to.  Possible, I could just use a value of 0 to indicate when a dialog box is already active, since this should not be a normally valid value (maybe -1?) 

Greg

Re: Detecting Multiple DXL Scripts
Mike.Scharnow - Tue Jul 02 17:19:09 EDT 2013

GregM_dxler - Tue Jul 02 15:39:46 EDT 2013

Did a search to find the entire thread on the massive memory leak.  It can be found at https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014629839

Turns out it is monitorWidth, not MonitorWidth....

I was able to read the current value (20) and also to change it.

Still have the same sort of problem, where I don't know what it will initially be set to.  Possible, I could just use a value of 0 to indicate when a dialog box is already active, since this should not be a normally valid value (maybe -1?) 

Greg

sorry about the typo.

monitorWidth is set to 20 unless you changed it ( I can't tell you why I know this. Otherwise I'd have to kill you.) :-)

 

-1 sounds ok

Re: Detecting Multiple DXL Scripts
Tony_Goodman - Wed Jul 03 09:36:09 EDT 2013

The functionality you describe is used by the Object Properties dialog in doors.

As Mike has mentioned already, this is implemented using a DB variable declared in the top-context. Your code needs to check this variable to see if it is null. If it is null then create the dialog box, otherwise just raise() the existing box.

put the following line into a dxl file in the DXL/config/baseWindowCallbacks folder. Note the long name for the DB so as not to conflict with other code.

DB myDialogBoxWithALongName = null

Your code should look something like this. Remember to explicitly set the DB variable to null when closing the dialog.

 

void doClose(DB db)
{
destroy(myDialogBoxWithALongName)
myDialogBoxWithALongName = null
}
 
if (!null myDialogBoxWithALongName)
{
raise(myDialogBoxWithALongName)
}
else
{
myDialogBoxWithALongName = create("My Dialog With a Long Name")
 
close(myDialogBoxWithALongName, true, doClose)
realize(myDialogBoxWithALongName)
show(myDialogBoxWithALongName)
}

 

Re: Detecting Multiple DXL Scripts
GregM_dxler - Wed Jul 03 10:48:05 EDT 2013

Tony_Goodman - Wed Jul 03 09:36:09 EDT 2013

The functionality you describe is used by the Object Properties dialog in doors.

As Mike has mentioned already, this is implemented using a DB variable declared in the top-context. Your code needs to check this variable to see if it is null. If it is null then create the dialog box, otherwise just raise() the existing box.

put the following line into a dxl file in the DXL/config/baseWindowCallbacks folder. Note the long name for the DB so as not to conflict with other code.

DB myDialogBoxWithALongName = null

Your code should look something like this. Remember to explicitly set the DB variable to null when closing the dialog.

 

void doClose(DB db)
{
destroy(myDialogBoxWithALongName)
myDialogBoxWithALongName = null
}
 
if (!null myDialogBoxWithALongName)
{
raise(myDialogBoxWithALongName)
}
else
{
myDialogBoxWithALongName = create("My Dialog With a Long Name")
 
close(myDialogBoxWithALongName, true, doClose)
realize(myDialogBoxWithALongName)
show(myDialogBoxWithALongName)
}

 

Hi Tony,

Thanks for the info.  This is a better solution, as it uses the normal DOORs operation instead of trying to reuse something else.  The only downside is having to have another file to keep track of, and the issue of offsite contractors where much of the drive structure is locked down from editing.

The only thing I had to remember is to restart DOORS after I added the file to the dxl/config/baseWindowCallbacks folder!

Greg

Re: Detecting Multiple DXL Scripts
GregM_dxler - Wed Jul 10 15:50:44 EDT 2013

Tony_Goodman - Wed Jul 03 09:36:09 EDT 2013

The functionality you describe is used by the Object Properties dialog in doors.

As Mike has mentioned already, this is implemented using a DB variable declared in the top-context. Your code needs to check this variable to see if it is null. If it is null then create the dialog box, otherwise just raise() the existing box.

put the following line into a dxl file in the DXL/config/baseWindowCallbacks folder. Note the long name for the DB so as not to conflict with other code.

DB myDialogBoxWithALongName = null

Your code should look something like this. Remember to explicitly set the DB variable to null when closing the dialog.

 

void doClose(DB db)
{
destroy(myDialogBoxWithALongName)
myDialogBoxWithALongName = null
}
 
if (!null myDialogBoxWithALongName)
{
raise(myDialogBoxWithALongName)
}
else
{
myDialogBoxWithALongName = create("My Dialog With a Long Name")
 
close(myDialogBoxWithALongName, true, doClose)
realize(myDialogBoxWithALongName)
show(myDialogBoxWithALongName)
}

 

Hi Tony,

Now I'm stumped again.  I try to update a DBE StatusField in the DB when it is raised and I get the dxl error "unassigned variable(StatusField)".  Do the DBE also need to be defined as a global variable?

Using your code, I added the declaration DBE StatusField at the beginning,

After the create DB, I added StatusField = field(myDialogBoxWithALongName, "Dialog Box Status", Initial", 20) to set it.

and then just after raise(myDialogBoxWithALongName), I added set(StatusField, "Raised")

I can get the unassigned variable error to not be displayed if I redefine StatusField again after the raise command, but the field doesn't get updated.

Where this would be nice is if say, I have the dialog box up, then I go to a different object and then try to relaunch the script it instead, raises the original dialog box and update it to the new object selected.

Any help would be much appreciated,

Thanks,
Greg

Re: Detecting Multiple DXL Scripts
Tony_Goodman - Fri Jul 12 05:47:22 EDT 2013

GregM_dxler - Wed Jul 10 15:50:44 EDT 2013

Hi Tony,

Now I'm stumped again.  I try to update a DBE StatusField in the DB when it is raised and I get the dxl error "unassigned variable(StatusField)".  Do the DBE also need to be defined as a global variable?

Using your code, I added the declaration DBE StatusField at the beginning,

After the create DB, I added StatusField = field(myDialogBoxWithALongName, "Dialog Box Status", Initial", 20) to set it.

and then just after raise(myDialogBoxWithALongName), I added set(StatusField, "Raised")

I can get the unassigned variable error to not be displayed if I redefine StatusField again after the raise command, but the field doesn't get updated.

Where this would be nice is if say, I have the dialog box up, then I go to a different object and then try to relaunch the script it instead, raises the original dialog box and update it to the new object selected.

Any help would be much appreciated,

Thanks,
Greg

The reason this doesn't work is that if myDialogBoxWithALongName already exists, it is not created but simply raised, thus returning control to the original instance of the script that is already running. The new instance of the script then terminates as raise() was the last statement.

So, the logic is

If the dialog already exists then raise() it and end.

If the dialog doesn't exist then create it as normal.

The following example works fine.

DBE StatusField = null

 
void doSetStatus(DB db)
{
set(StatusField, "Raised")
}
 
void doClose(DB db)
{
destroy(myDialogBoxWithALongName)
myDialogBoxWithALongName = null
}
 
if (!null myDialogBoxWithALongName)
{

    // just make this one call and end

raise(myDialogBoxWithALongName)
}
else
{
myDialogBoxWithALongName = create("My Dialog With a Long Name")
 
StatusField = field(myDialogBoxWithALongName, "Dialog Box Status", "Initial", 20)
 
apply(myDialogBoxWithALongName, "Set Status", doSetStatus)
close(myDialogBoxWithALongName, true, doClose)
realize(myDialogBoxWithALongName)
show(myDialogBoxWithALongName)
}

 

 

Re: Detecting Multiple DXL Scripts
GregM_dxler - Mon Jul 15 09:09:19 EDT 2013

Tony_Goodman - Fri Jul 12 05:47:22 EDT 2013

The reason this doesn't work is that if myDialogBoxWithALongName already exists, it is not created but simply raised, thus returning control to the original instance of the script that is already running. The new instance of the script then terminates as raise() was the last statement.

So, the logic is

If the dialog already exists then raise() it and end.

If the dialog doesn't exist then create it as normal.

The following example works fine.

DBE StatusField = null

 
void doSetStatus(DB db)
{
set(StatusField, "Raised")
}
 
void doClose(DB db)
{
destroy(myDialogBoxWithALongName)
myDialogBoxWithALongName = null
}
 
if (!null myDialogBoxWithALongName)
{

    // just make this one call and end

raise(myDialogBoxWithALongName)
}
else
{
myDialogBoxWithALongName = create("My Dialog With a Long Name")
 
StatusField = field(myDialogBoxWithALongName, "Dialog Box Status", "Initial", 20)
 
apply(myDialogBoxWithALongName, "Set Status", doSetStatus)
close(myDialogBoxWithALongName, true, doClose)
realize(myDialogBoxWithALongName)
show(myDialogBoxWithALongName)
}

 

 

Hi Tony,

Thanks for the additional input.  I was thinking that since the dialog box was global, then all the elements in the dialog box would also be global.  I was able to get it to work by including the DBE declarations in with the DB declaration.  Then to help any programmer to understand the script, I commented out the "normal" declarations in the script and added a note that they are declared in the xxxdeclarations.dxl file in \DXL/config/baseWindowCallbacks folder.

Greg 

Re: Detecting Multiple DXL Scripts
Tony_Goodman - Tue Jul 16 10:21:27 EDT 2013

GregM_dxler - Mon Jul 15 09:09:19 EDT 2013

Hi Tony,

Thanks for the additional input.  I was thinking that since the dialog box was global, then all the elements in the dialog box would also be global.  I was able to get it to work by including the DBE declarations in with the DB declaration.  Then to help any programmer to understand the script, I commented out the "normal" declarations in the script and added a note that they are declared in the xxxdeclarations.dxl file in \DXL/config/baseWindowCallbacks folder.

Greg 

I would recommend keeping the number of global variables to a minimum. Apart from your example above, I cannot envisage a situation where you would need global DBEs.